home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / iritsm3s.zip / ALLOCATE.C < prev    next >
C/C++ Source or Header  |  1992-01-28  |  12KB  |  371 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d polygonal solid modeller.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.2, Mar. 1990   *
  5. ******************************************************************************
  6. *   Dynamic allocation module of "Irit" - the 3d polygonal solid modeller.   *
  7. *****************************************************************************/
  8.  
  9. /* #define DEBUG            Print more messages in free/allocating. */
  10.  
  11. #ifdef __MSDOS__
  12. #include <alloc.h>
  13. #include <time.h>
  14. #endif /* __MSDOS__ */
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include "program.h"
  19. #include "allocate.h"
  20. #include "attribut.h"
  21. #include "ctrl-brk.h"
  22. #include "graphgen.h"
  23. #include "windows.h"
  24.  
  25. #define MAGIC_FREE_NUM    1234567890L     /* Used in DEBUG mode to mark free. */
  26.  
  27. #define ALLOCATE_NUM    100       /* Number of objects to allocate at once. */
  28.  
  29. #ifdef __MSDOS__
  30. /* Used to say when to update core left on screen: */
  31. static time_t LastTimeAlloc = 0;
  32. #endif /* __MSDOS__ */
  33.  
  34. /* Used for fast reallocation of most common object types: */
  35. static VertexStruct *VertexFreedList = NULL;
  36. static PolygonStruct *PolygonFreedList = NULL;
  37. static ObjectStruct *ObjectFreedList = NULL;
  38.  
  39. static void FreePolygonList(PolygonStruct * PPoly);
  40. static void FreeVertexList(VertexStruct * VFirst);
  41.  
  42. /*****************************************************************************
  43. * My Routine to    allocate dynamic memory. All program requests must call this *
  44. * routine (no direct call to malloc). Dies if no memory.             *
  45. * In order to reduce the overhead of the allocation, basic objects are       *
  46. * allocated in ALLOCATE_NUM number of objects blocks.                 *
  47. *****************************************************************************/
  48. char *MyMalloc(unsigned int Size, AllocateStructType Type)
  49. {
  50.     char *p;
  51.     int i;
  52.  
  53. #   ifdef __MSDOS__
  54.     if (time(NULL) != LastTimeAlloc) {
  55.         if (GlblWasCtrlBrk) FatalError(NULL);      /* Jump to main loop. */
  56.         WndwStatusWindowUpdate();               /* Print free memory. */
  57.         LastTimeAlloc = time(NULL);
  58.         }
  59. #   endif /* __MSDOS__ */
  60.  
  61.     switch (Type) {
  62.     case ALLOC_VERTEX:
  63. #        ifdef DEBUG
  64.         fprintf(stderr, "MyMalloc: Allocate vertex type");
  65. #        endif /* DEBUG */
  66.         if (VertexFreedList != NULL) {
  67.         p = (char *) VertexFreedList;
  68.         VertexFreedList = VertexFreedList -> Pnext;
  69.         }
  70.         else {
  71.         VertexStruct *V;
  72.  
  73.         /* Allocate ALLOCATE_NUM objects, returns first one as new   */
  74.         /* and chain together the rest of them into the free list.   */
  75.         p = malloc(Size * ALLOCATE_NUM);
  76.         V = (VertexStruct *) p;
  77.         if (V != NULL) {
  78.             for (i = 1; i < ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
  79.             V[ALLOCATE_NUM-1].Pnext = NULL;
  80.             VertexFreedList = &V[1];
  81.         }
  82.         }
  83.         break;
  84.     case ALLOC_POLYGON:
  85. #        ifdef DEBUG
  86.         fprintf(stderr, "MyMalloc: Allocate polygon type");
  87. #        endif /* DEBUG */
  88.         if (PolygonFreedList != NULL) {
  89.         p = (char *) PolygonFreedList;
  90.         PolygonFreedList = PolygonFreedList -> Pnext;
  91.         }
  92.         else {
  93.         PolygonStruct *V;
  94.  
  95.         /* Allocate ALLOCATE_NUM objects, returns first one as new   */
  96.         /* and chain together the rest of them into the free list.   */
  97.         p = malloc(Size * ALLOCATE_NUM);
  98.         V = (PolygonStruct *) p;
  99.         if (V != NULL) {
  100.             for (i = 1; i < ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
  101.             V[ALLOCATE_NUM-1].Pnext = NULL;
  102.             PolygonFreedList = &V[1];
  103.         }
  104.         }
  105.         break;
  106.     case ALLOC_OBJECT:
  107. #        ifdef DEBUG
  108.         fprintf(stderr, "MyMalloc: Allocate object type");
  109. #        endif /* DEBUG */
  110.         if (ObjectFreedList != NULL) {
  111.         p = (char *) ObjectFreedList;
  112.         ObjectFreedList = ObjectFreedList -> Pnext;
  113.         }
  114.         else {
  115.         ObjectStruct *V;
  116.  
  117.         /* Allocate ALLOCATE_NUM objects, returns first one as new   */
  118.         /* and chain together the rest of them into the free list.   */
  119.         p = malloc(Size * ALLOCATE_NUM);
  120.         V = (ObjectStruct *) p;
  121.         if (V != NULL) {
  122.             for (i = 1; i < ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
  123.             V[ALLOCATE_NUM-1].Pnext = NULL;
  124.             ObjectFreedList = &V[1];
  125.         }
  126.         }
  127.         break;
  128.     default:
  129. #        ifdef DEBUG
  130.         fprintf(stderr, "MyMalloc: Allocate undefined Type %d", Type);
  131. #        endif /* DEBUG */
  132.         p = malloc(Size);
  133.         break;
  134.     }
  135.  
  136. #   ifdef DEBUG
  137.     fprintf(stderr, " (Size = %d, ptr = %p)\n", Size, p);
  138. #   endif /* DEBUG */
  139.  
  140.     if (p != NULL) return p;
  141.  
  142.     WndwInputWindowPutStr("Not enough memory - program cannt continue");
  143.     GlblFatalError = TRUE;
  144.     /* Long jump to main intraction loop - irit.c module */
  145.     longjmp(GlblLongJumpBuffer, 2);
  146.  
  147.     return NULL;                /* Only makes warnings silent... */
  148. }
  149.  
  150. /*****************************************************************************
  151. * Routine to free a given structure, which is not needed any more         *
  152. * Note usually only object will be given directly to MyFree which         *
  153. * recursively free its structure...                         *
  154. * Also, it is perfectly legal to call with NULL to MyFree...                 *
  155. *****************************************************************************/
  156. void MyFree(char *p, AllocateStructType Type)
  157. {
  158.     int index;
  159.     char Line[LINE_LEN];
  160.     ObjectStruct *PObj;
  161.  
  162. #   ifdef __MSDOS__
  163.     if (time(NULL) != LastTimeAlloc) {
  164.         if (GlblWasCtrlBrk) FatalError(NULL);      /* Jump to main loop. */
  165.         WndwStatusWindowUpdate();               /* Print free memory. */
  166.         LastTimeAlloc = time(NULL);
  167.         }
  168. #   endif /* __MSDOS__ */
  169.  
  170.     if (p == NULL) return;
  171.  
  172. #   ifdef DEBUG
  173.     /* The following might fail if a record is freed without any usage!  */
  174.     if (*((long *) p) == MAGIC_FREE_NUM)
  175.         FatalError("MyFree:Free the same record twice, dies");
  176.     *((long *) p) = MAGIC_FREE_NUM;          /* And set it for next time... */
  177. #   endif /* DEBUG */
  178.  
  179.     switch (Type) {
  180.     case ALLOC_VERTEX:
  181. #        ifdef DEBUG
  182.         fprintf(stderr, "MyFree: free vertex type\n");
  183. #        endif /* DEBUG */
  184.         FreeVertexList((VertexStruct *) p);
  185.         break;
  186.     case ALLOC_POLYGON:
  187. #        ifdef DEBUG
  188.         fprintf(stderr, "MyFree: free polygon type\n");
  189. #        endif /* DEBUG */
  190.         FreePolygonList((PolygonStruct *) p);
  191.         break;
  192.     case ALLOC_OBJECT:
  193. #        ifdef DEBUG
  194.         fprintf(stderr, "MyFree: free object type\n");
  195. #        endif /* DEBUG */
  196.         PObj = (ObjectStruct *) p;
  197.         if (PObj -> Count > 1) {
  198.         /* Do not free object - just decrease its reference count.   */
  199.         PObj -> Count--;
  200.                 break;
  201.             }
  202.         switch (((ObjectStruct *) p) -> ObjType) {
  203.         case UNDEF_OBJ:
  204.             break;
  205.         case POLY_OBJ:               /* Free the polygon list. */
  206.             MyFree((char *) (PObj -> U.Pl.P), ALLOC_POLYGON);
  207.             ReleaseStrAttrib(PObj);
  208.             break;
  209.         case NUMERIC_OBJ:
  210.         case VECTOR_OBJ:
  211.         case CTLPT_OBJ:
  212.         case MATRIX_OBJ:
  213.         case STRING_OBJ:
  214.             break;
  215.         case OBJ_LIST_OBJ:  /* Need to dereference elements in list. */
  216.             index = 0;
  217.             while (index < MAX_OBJ_LIST &&
  218.                PObj -> U.PObjList[index] != NULL) {
  219.             if (PObj -> U.PObjList[index] -> Count-- == 1)
  220.                 MyFree((char *) (PObj -> U.PObjList[index]),
  221.                    ALLOC_OBJECT);
  222.             index++;
  223.             }
  224.             break;
  225.         case CURVE_OBJ:
  226.             CagdCrvFree(PObj -> U.Crv.Crv);
  227.             if (PObj -> U.Crv.PLPolys)
  228.             CagdPolylineFree(PObj -> U.Crv.PLPolys);
  229.             if (PObj -> U.Crv.CtlPoly)
  230.             CagdPolylineFree(PObj -> U.Crv.CtlPoly);
  231.             ReleaseStrAttrib(PObj);
  232.             break;
  233.         case SURFACE_OBJ:
  234.             CagdSrfFree(PObj -> U.Srf.Srf);
  235.             if (PObj -> U.Srf.PLPolys)
  236.             CagdPolylineFreeList(PObj -> U.Srf.PLPolys);
  237.             if (PObj -> U.Srf.CtlMesh)
  238.             CagdPolylineFreeList(PObj -> U.Srf.CtlMesh);
  239.             if (PObj -> U.Srf.Polygons)
  240.             MyFree((char *) PObj -> U.Srf.Polygons, ALLOC_OBJECT);
  241.             ReleaseStrAttrib(PObj);
  242.             break;
  243.         default:         /* Kill the program - something is WRONG! */
  244.             sprintf(Line,
  245.                 "MyFree: Attempt to free undefined Object type %d",
  246.                             PObj -> ObjType);
  247.             FatalError(Line);
  248.             break;
  249.         }
  250.         /* Add it to global freed object list: */
  251.         PObj -> Pnext = ObjectFreedList;
  252.         ObjectFreedList = PObj;
  253.         break;
  254.     default:
  255. #        ifdef DEBUG
  256.         fprintf(stderr, "MyFree: Free undefined Type %d\n", Type);
  257. #        endif /* DEBUG */
  258.         free(p);
  259.         break;
  260.     }
  261. }
  262.  
  263. /*****************************************************************************
  264. *   Routine to free a polygon list each consists of circular vertex list.    *
  265. *****************************************************************************/
  266. static void FreePolygonList(PolygonStruct *PPoly)
  267. {
  268.     PolygonStruct *Ptemp, *PPolyHead = PPoly;
  269.  
  270. #   ifdef DEBUG
  271.     fprintf(stderr, "FreePolygonList: free polygon list\n");
  272. #   endif /* DEBUG */
  273.  
  274.     while (PPoly) {
  275.     FreeVertexList(PPoly -> V);
  276.     Ptemp = PPoly;
  277.     PPoly = PPoly -> Pnext;
  278.     }
  279.  
  280.     /* Now chain this new list to the global freed polygon list: */
  281.     Ptemp -> Pnext = PolygonFreedList;
  282.     PolygonFreedList = PPolyHead;
  283. }
  284.  
  285. /*****************************************************************************
  286. *   Routine to free a circular vertex list - one polygon contour.         *
  287. *****************************************************************************/
  288. static void FreeVertexList(VertexStruct *VFirst)
  289. {
  290.     VertexStruct *V = VFirst, *Vtemp;
  291.  
  292. #   ifdef DEBUG
  293.     fprintf(stderr, "FreeVertexList: free vertex list\n");
  294. #   endif /* DEBUG */
  295.  
  296.     if (VFirst == NULL) return;
  297.  
  298.     do {
  299.     Vtemp = V;
  300.     V = V -> Pnext;
  301.     }
  302.     while (V != NULL && V != VFirst); /* Both - circular or NULL terminated. */
  303.  
  304.     /* Now chain this new list to the global freed vertex list: */
  305.     Vtemp -> Pnext = VertexFreedList;
  306.     VertexFreedList = VFirst;
  307. }
  308.  
  309. /*****************************************************************************
  310. * Allocate one Vertex Structure:                         *
  311. *****************************************************************************/
  312. VertexStruct * AllocVertex(ByteType Count, ByteType Tags,
  313.                 PolygonStruct * PAdj, VertexStruct * Pnext)
  314. {
  315.     VertexStruct *p;
  316.  
  317.     p = (VertexStruct *) MyMalloc(sizeof(VertexStruct), ALLOC_VERTEX);
  318.  
  319.     p -> Normal[0] = p -> Normal[1] = p -> Normal[2] = 0.0;
  320.     p -> Count = Count;
  321.     p -> Tags = Tags;
  322.     p -> Pnext = Pnext;
  323.     p -> PAdj = PAdj;
  324.  
  325.     return p;
  326. }
  327.  
  328. /*****************************************************************************
  329. * Allocate one Polygon Structure:                         *
  330. *****************************************************************************/
  331. PolygonStruct * AllocPolygon(ByteType Count, ByteType Tags,
  332.                 VertexStruct * V, PolygonStruct * Pnext)
  333. {
  334.     PolygonStruct *p;
  335.  
  336.     p = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct), ALLOC_POLYGON);
  337.  
  338.     p -> Plane[0] = p -> Plane[1] = p -> Plane[2] = p -> Plane[3] = 0.0;
  339.     p -> Count = Count;
  340.     p -> Tags = Tags;
  341.     p -> V = V;
  342.     p -> Pnext = Pnext;
  343.  
  344.     return p;
  345. }
  346.  
  347. /*****************************************************************************
  348. * Allocate one Object Structure:                         *
  349. *****************************************************************************/
  350. ObjectStruct * AllocObject(char *Name, IritObjectType ObjType,
  351.                          ObjectStruct * Pnext)
  352. {
  353.     ObjectStruct *p;
  354.  
  355.     p = (ObjectStruct *) MyMalloc(sizeof(ObjectStruct), ALLOC_OBJECT);
  356.  
  357.     strcpy(p -> Name, Name);
  358.     p -> ObjType = ObjType;
  359.     p -> Count = 1;
  360.     p -> Pnext = Pnext;
  361.     p -> U.Pl.P = NULL;                /* To be on the safe size... */
  362.     p -> U.Crv.PLPolys = NULL;
  363.     p -> U.Crv.CtlPoly = NULL;
  364.     p -> U.Srf.PLPolys = NULL;
  365.     p -> U.Srf.CtlMesh = NULL;
  366.     p -> U.Srf.Polygons = NULL;
  367.     p -> U.Attr.NumStrAttribs = 0;
  368.  
  369.     return p;
  370. }
  371.